On voit que les deux premières colonnes (X & id) sont inutiles pour nos analyses, on va donc les supprimer
data <- read.csv("data/train.csv")
str(data)
## 'data.frame': 103904 obs. of 25 variables:
## $ X : int 0 1 2 3 4 5 6 7 8 9 ...
## $ id : int 70172 5047 110028 24026 119299 111157 82113 96462 79485 65725 ...
## $ Gender : chr "Male" "Male" "Female" "Female" ...
## $ Customer.Type : chr "Loyal Customer" "disloyal Customer" "Loyal Customer" "Loyal Customer" ...
## $ Age : int 13 25 26 25 61 26 47 52 41 20 ...
## $ Type.of.Travel : chr "Personal Travel" "Business travel" "Business travel" "Business travel" ...
## $ Class : chr "Eco Plus" "Business" "Business" "Business" ...
## $ Flight.Distance : int 460 235 1142 562 214 1180 1276 2035 853 1061 ...
## $ Inflight.wifi.service : int 3 3 2 2 3 3 2 4 1 3 ...
## $ Departure.Arrival.time.convenient: int 4 2 2 5 3 4 4 3 2 3 ...
## $ Ease.of.Online.booking : int 3 3 2 5 3 2 2 4 2 3 ...
## $ Gate.location : int 1 3 2 5 3 1 3 4 2 4 ...
## $ Food.and.drink : int 5 1 5 2 4 1 2 5 4 2 ...
## $ Online.boarding : int 3 3 5 2 5 2 2 5 3 3 ...
## $ Seat.comfort : int 5 1 5 2 5 1 2 5 3 3 ...
## $ Inflight.entertainment : int 5 1 5 2 3 1 2 5 1 2 ...
## $ On.board.service : int 4 1 4 2 3 3 3 5 1 2 ...
## $ Leg.room.service : int 3 5 3 5 4 4 3 5 2 3 ...
## $ Baggage.handling : int 4 3 4 3 4 4 4 5 1 4 ...
## $ Checkin.service : int 4 1 4 1 3 4 3 4 4 4 ...
## $ Inflight.service : int 5 4 4 4 3 4 5 5 1 3 ...
## $ Cleanliness : int 5 1 5 2 3 1 2 4 2 2 ...
## $ Departure.Delay.in.Minutes : int 25 1 0 11 0 0 9 4 0 0 ...
## $ Arrival.Delay.in.Minutes : num 18 6 0 9 0 0 23 0 0 0 ...
## $ satisfaction : chr "neutral or dissatisfied" "neutral or dissatisfied" "satisfied" "neutral or dissatisfied" ...
# On retire les colonnes inutiles
data <- data[,c(-1,-2)]
# On modifie les noms des colonnes pour le style ;-)
row.names(data) <- paste("n°", sep="", 1:dim(data)[1])
# On renomme les colonnes pour avoir des noms moins longs (Utile pour l'affichage)
colnames(data) <- c("Genre", "Fidélité", "Age", "Type.du.vol", "Classe", "Distance", "Wifi", "Horaire.pratique", "Facilité.resevation", "Emplacement.porte", "Nourriture", "Enregistrement.en.ligne", "Siege.confort", "Loisir", "On.board.service", "Espace.jambe", "Gestion.bagage", "Checkin.service", "Inflight.service", "Propreté", "Retard.depart", "Retard.arrivé", "Satisfaction")
str(data)
## 'data.frame': 103904 obs. of 23 variables:
## $ Genre : chr "Male" "Male" "Female" "Female" ...
## $ Fidélité : chr "Loyal Customer" "disloyal Customer" "Loyal Customer" "Loyal Customer" ...
## $ Age : int 13 25 26 25 61 26 47 52 41 20 ...
## $ Type.du.vol : chr "Personal Travel" "Business travel" "Business travel" "Business travel" ...
## $ Classe : chr "Eco Plus" "Business" "Business" "Business" ...
## $ Distance : int 460 235 1142 562 214 1180 1276 2035 853 1061 ...
## $ Wifi : int 3 3 2 2 3 3 2 4 1 3 ...
## $ Horaire.pratique : int 4 2 2 5 3 4 4 3 2 3 ...
## $ Facilité.resevation : int 3 3 2 5 3 2 2 4 2 3 ...
## $ Emplacement.porte : int 1 3 2 5 3 1 3 4 2 4 ...
## $ Nourriture : int 5 1 5 2 4 1 2 5 4 2 ...
## $ Enregistrement.en.ligne: int 3 3 5 2 5 2 2 5 3 3 ...
## $ Siege.confort : int 5 1 5 2 5 1 2 5 3 3 ...
## $ Loisir : int 5 1 5 2 3 1 2 5 1 2 ...
## $ On.board.service : int 4 1 4 2 3 3 3 5 1 2 ...
## $ Espace.jambe : int 3 5 3 5 4 4 3 5 2 3 ...
## $ Gestion.bagage : int 4 3 4 3 4 4 4 5 1 4 ...
## $ Checkin.service : int 4 1 4 1 3 4 3 4 4 4 ...
## $ Inflight.service : int 5 4 4 4 3 4 5 5 1 3 ...
## $ Propreté : int 5 1 5 2 3 1 2 4 2 2 ...
## $ Retard.depart : int 25 1 0 11 0 0 9 4 0 0 ...
## $ Retard.arrivé : num 18 6 0 9 0 0 23 0 0 0 ...
## $ Satisfaction : chr "neutral or dissatisfied" "neutral or dissatisfied" "satisfied" "neutral or dissatisfied" ...
Petit avant gout des données :
paged_table(data)
Les notes sont assez homogènes, elles ont toutes :
Un 1er quartile égal à 2 ou 3
Une médiane égal à 3 ou 4.
Un 3-ème quartile égale à 4 ou 5.
Les moyennes pour les notes vont de 2.73 à 3.64.
On peut aussi observer les autres variables mais elles ne seront pas importantes pour la mise en oeuvre de l’ACP
summary(data)
## Genre Fidélité Age Type.du.vol
## Length:103904 Length:103904 Min. : 7.00 Length:103904
## Class :character Class :character 1st Qu.:27.00 Class :character
## Mode :character Mode :character Median :40.00 Mode :character
## Mean :39.38
## 3rd Qu.:51.00
## Max. :85.00
##
## Classe Distance Wifi Horaire.pratique
## Length:103904 Min. : 31 Min. :0.00 Min. :0.00
## Class :character 1st Qu.: 414 1st Qu.:2.00 1st Qu.:2.00
## Mode :character Median : 843 Median :3.00 Median :3.00
## Mean :1189 Mean :2.73 Mean :3.06
## 3rd Qu.:1743 3rd Qu.:4.00 3rd Qu.:4.00
## Max. :4983 Max. :5.00 Max. :5.00
##
## Facilité.resevation Emplacement.porte Nourriture Enregistrement.en.ligne
## Min. :0.000 Min. :0.000 Min. :0.000 Min. :0.00
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.00
## Median :3.000 Median :3.000 Median :3.000 Median :3.00
## Mean :2.757 Mean :2.977 Mean :3.202 Mean :3.25
## 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.00
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.00
##
## Siege.confort Loisir On.board.service Espace.jambe
## Min. :0.000 Min. :0.000 Min. :0.000 Min. :0.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000
## Median :4.000 Median :4.000 Median :4.000 Median :4.000
## Mean :3.439 Mean :3.358 Mean :3.382 Mean :3.351
## 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.000
##
## Gestion.bagage Checkin.service Inflight.service Propreté
## Min. :1.000 Min. :0.000 Min. :0.00 Min. :0.000
## 1st Qu.:3.000 1st Qu.:3.000 1st Qu.:3.00 1st Qu.:2.000
## Median :4.000 Median :3.000 Median :4.00 Median :3.000
## Mean :3.632 Mean :3.304 Mean :3.64 Mean :3.286
## 3rd Qu.:5.000 3rd Qu.:4.000 3rd Qu.:5.00 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.00 Max. :5.000
##
## Retard.depart Retard.arrivé Satisfaction
## Min. : 0.00 Min. : 0.00 Length:103904
## 1st Qu.: 0.00 1st Qu.: 0.00 Class :character
## Median : 0.00 Median : 0.00 Mode :character
## Mean : 14.82 Mean : 15.18
## 3rd Qu.: 12.00 3rd Qu.: 13.00
## Max. :1592.00 Max. :1584.00
## NA's :310
On récupère toutes les données quantitatives et la satisfaction.
On ne prend que les 5000 premières lignes car le data set est trop gros (+100 000 lignes)
# On récupère Âge/Distance du vol/Retard Depart/Retard Arrivé (colonne 3/6/21/22), les notes (colonnes 7 à 20) et la satisfaction (colonne 23)
data_bis <- data[1:5000,c(3,6,21,22,7:20,23)]
res <- PCA(data_bis, quanti.sup=1:4, quali.sup=19, graph=FALSE)
## Warning in PCA(data_bis, quanti.sup = 1:4, quali.sup = 19, graph = FALSE):
## Missing values are imputed by the mean of the variable: you should use the
## imputePCA function of the missMDA package
On revient sur nos données pour voir s’il n’y a pas eu de changement trop brutal :
summary(data_bis)
## Age Distance Retard.depart Retard.arrivé
## Min. : 7.00 Min. : 67.0 Min. : 0.00 Min. : 0.00
## 1st Qu.:27.00 1st Qu.: 409.8 1st Qu.: 0.00 1st Qu.: 0.00
## Median :39.00 Median : 861.0 Median : 0.00 Median : 0.00
## Mean :39.13 Mean :1205.4 Mean : 15.06 Mean : 15.49
## 3rd Qu.:51.00 3rd Qu.:1771.5 3rd Qu.: 14.00 3rd Qu.: 14.00
## Max. :85.00 Max. :4983.0 Max. :480.00 Max. :471.00
## NA's :13
## Wifi Horaire.pratique Facilité.resevation Emplacement.porte
## Min. :0.000 Min. :0.000 Min. :0.000 Min. :1.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000
## Median :3.000 Median :3.000 Median :3.000 Median :3.000
## Mean :2.741 Mean :3.033 Mean :2.767 Mean :2.972
## 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.000
##
## Nourriture Enregistrement.en.ligne Siege.confort Loisir
## Min. :0.000 Min. :0.000 Min. :1.000 Min. :0.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:2.000
## Median :3.000 Median :3.000 Median :4.000 Median :4.000
## Mean :3.218 Mean :3.253 Mean :3.421 Mean :3.339
## 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:4.250 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.000
##
## On.board.service Espace.jambe Gestion.bagage Checkin.service
## Min. :0.000 Min. :0.000 Min. :1.000 Min. :1.000
## 1st Qu.:2.000 1st Qu.:2.000 1st Qu.:3.000 1st Qu.:3.000
## Median :4.000 Median :4.000 Median :4.000 Median :3.000
## Mean :3.361 Mean :3.338 Mean :3.623 Mean :3.316
## 3rd Qu.:4.000 3rd Qu.:4.000 3rd Qu.:5.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000 Max. :5.000 Max. :5.000
##
## Inflight.service Propreté Satisfaction
## Min. :0.000 Min. :1.000 Length:5000
## 1st Qu.:3.000 1st Qu.:2.000 Class :character
## Median :4.000 Median :3.000 Mode :character
## Mean :3.651 Mean :3.268
## 3rd Qu.:5.000 3rd Qu.:4.000
## Max. :5.000 Max. :5.000
##
Les individus ou variables peuvent être proches dans le plan mais eloignés dans l’espace s’ils sont mal représentés dans le plan. Ainsi, il est important d’expliquer les individus avec des variables bien representées dans le plan. Pour cela on veillera à ne pas prendre les variables et individus ayant un cos2 trop bas. Ici on choisit un cos2 égale à 0.58 afin d’avoir au moins 4 variables à utiliser afin d’expliquer nos individus sur les axes 1 et 2.
Ici l’axe 1 va faire le contraste entre le confort à bord (droite) et l’inconfort (gauche), tandis que l’axe 2 fera le contraste entre les aspects techniques pour ce qui concerne le vol.
Les variables quantitatives supplémentaires ne sont pas du tout interprétables
plot(res,select="cos2 0.58", choix="varcor")
On peut voir une nette séparation entre les individus satisfaits et non satisfaits. Les individus satisfaits sont ceux s’étant amusé et ayant trouvé l’avion propre. À l’inverse les individus non satisfaits n’ont pas trouvé l’avion propre et ne se sont pas amusés. On ne peut pas vraiment dire pour l’instant si la facilité de réservation et le wifi à bord influent. Ici par exemple l’individu n°686 ne s’est pas amusé à bord et n’a pas non plus trouvé l’avion propre et il n’est pas satisfait.
plot(res,habillage=19, select="cos2 0.58", choix="ind")
L’individu qui contribue le plus à l’axe 1 : 0.15%.
Il y a 40 individus qui y contribuent pour plus de 0.1%
On n’a pas d’individus atypiques, ce qui est normal car nos données sont des notes entre 0 et 5 et on a vu qu’elles étaient assez homogènes
max(res$ind$contrib[,1])
## [1] 0.1527594
sum((res$ind$contrib[,1] > 0.1)*1)
## [1] 40
On peut voir premièrement que les 3 premiers axes expliquent bien l’inertie sur les données. Les axes étant orthogonaux, les axes 1 et 2 prennent en compte 26.99% + 16.90% = 43.89% du jeu de données expliquent 44.56% de l’inertie. On peut aussi voir que l’axe 2 et 3 expliquent à peu près autant l’un que l’autre l’inertie, ainsi on pourra aussi visualiser les données projetées sur le plan formé par l’axe 1 et 3 (même 2 et 3).
barplot(res$eig[,2], col=rainbow(n=14,alpha=0.6,start=0,end=0.33),main="Pourcentage d'inertie expliquée par chaque axe", ylab="Contribution en %")
lines(seq(0.75,16.3,(16.3-0.75)/13),res$eig[,2],type="b", xlim=c(0,max(res$eig[,2])+10))
text(seq(0.75,16.3,(16.3-0.75)/13),res$eig[,2]-1, paste(round(res$eig[,2],2),"%"), cex=0.7)
#text(5,22,paste(round(res$eig[,2],2)[1],"% +",round(res$eig[,2],2)[2],"% = ",round(res$eig[,2],2)[1]+round(res$eig[,2],2)[2],"%",sep=""))
On a un nouveau cercle de corrélation, ici on voit que :
plot(res, select="cos2 0.58", choix="varcor", axes = c(1,3))
Les passagers sont en général plus satisfait quand ils se sont amusé et que le service était agréable.
plot(res, habillage=19, select="cos2 0.58", choix="ind", axes = c(1,3))
Ici on a le cercle de corrélation avec l’axe 2 et 3:
plot(res, select="cos2 0.6", choix="varcor", axes = c(2,3))
Il n’y a pas grand-chose à interpréter car le barycentre des voyageurs satisfaite et non satisfaits sont tout les 2 au centre de gravité de ce plan.
plot(res, choix="ind", axes = c(2,3))
Certains passagés ayant attribué comme notes 0 pour certaines catégories du vol on décide de ne pas faire de transformation par l’inverse car \(\frac{1}{0}\) est un quotient indéterminé
On effectue la transformation ”double centrage” sur les données log-transformées afin de voir si on peut faire gagner en contribution les premières composantes afin d’être plus précis lors de nos analyses.
data_bis2 <- log(data_bis[,c(-4:-1,-19)])
data_bis2 <- t(scale(t(data_bis2)))
res2 <- PCA(data_bis2, graph=FALSE)
## Warning in PCA(data_bis2, graph = FALSE): Missing values are imputed by the mean
## of the variable: you should use the imputePCA function of the missMDA package
barplot(res2$eig[,2], col=rainbow(n=14,alpha=0.6,start=0.33,end=0.66),main="Pourcentage d'intertie expliquée par chaque axe\n(Données log-transformées) ", ylab="Contribution en %")
lines(seq(0.75,16.3,(16.3-0.75)/13),res2$eig[,2],type="b")
text(seq(0.75,16.3,(16.3-0.75)/13),res2$eig[,2]-1, paste(round(res2$eig[,2],2),"%"), cex=0.7)
On effectue la transformation ”double centrage” sur les données transformées par racine carrée afin de voir si on peut faire gagner en contribution les premières composantes afin d’être plus précis lors de nos analyses.
data_bis3 <- sqrt(data_bis[,c(-4:-1,-19)])
data_bis3 <- t(scale(t(data_bis3)))
res3 <- PCA(data_bis3, graph=FALSE)
barplot(res3$eig[,2], col=rainbow(n=14,alpha=0.6,start=0.66,end=1),main="Pourcentage d'intertie expliquée par chaque axe\n(Données transformées par racine carrée)", ylab="Contribution en %")
lines(seq(0.75,16.3,(16.3-0.75)/13),res3$eig[,2],type="b")
text(seq(0.75,16.3,(16.3-0.75)/13),res3$eig[,2]-1, paste(round(res3$eig[,2],2),"%"), cex=0.7)
Les transformations ne nous ont pas fait gagner plus d’informations au niveau des 2 premiers axes, on s’arrête là pour l’ACP.
Ici on a pu étudier l’impacte des variable quantitative sur la satisfaction des gens pour un trajet en avion. Il en est ressorti que les services proposés dans l’avion et le confort à bord sont un aspect primordial pour la satisfaction des voyageurs.